// $ANTLR 3.2 Sep 23, 2009 12:02:23 D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g 2010-05-10 20:51:49

package astudy.parser.calc;


import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;


import org.antlr.runtime.tree.*;

public class CalculatorParser extends Parser {
    public static final String[] tokenNames = new String[] {
        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "PLUS", "MINUS", "MULT", "DIV", "MOD", "COMMA", "LPAREN", "RPAREN", "DOT", "INTEGER", "FLOAT", "NUMBER", "WHITESPACE", "EOL", "DIGIT", "ABS", "SIN", "COS", "SQRT", "POW", "LN", "LOG"
    };
    public static final int INTEGER=13;
    public static final int LN=24;
    public static final int MOD=8;
    public static final int LOG=25;
    public static final int NUMBER=15;
    public static final int WHITESPACE=16;
    public static final int FLOAT=14;
    public static final int SQRT=22;
    public static final int MULT=6;
    public static final int MINUS=5;
    public static final int EOF=-1;
    public static final int LPAREN=10;
    public static final int ABS=19;
    public static final int RPAREN=11;
    public static final int EOL=17;
    public static final int POW=23;
    public static final int SIN=20;
    public static final int COMMA=9;
    public static final int COS=21;
    public static final int PLUS=4;
    public static final int DIGIT=18;
    public static final int DIV=7;
    public static final int DOT=12;

    // delegates
    // delegators


        public CalculatorParser(TokenStream input) {
            this(input, new RecognizerSharedState());
        }
        public CalculatorParser(TokenStream input, RecognizerSharedState state) {
            super(input, state);
             
        }
        
    protected TreeAdaptor adaptor = new CommonTreeAdaptor();

    public void setTreeAdaptor(TreeAdaptor adaptor) {
        this.adaptor = adaptor;
    }
    public TreeAdaptor getTreeAdaptor() {
        return adaptor;
    }

    public String[] getTokenNames() { return CalculatorParser.tokenNames; }
    public String getGrammarFileName() { return "D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g"; }


    	private enum Type {
    		FLOAT("float"),
    		INTEGER("integer"),
    		String("string");
    		private String type;
    		Type(String type) {
    			this.type = type;
    		}
    		@Override
    		public String toString() { return this.type; }
    	}


    public static class call_return extends ParserRuleReturnScope {
        public Number value;
        public Type type;
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "call"
    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:78:1: call returns [Number value, Type type] : expression EOL ;
    public final CalculatorParser.call_return call() throws RecognitionException {
        CalculatorParser.call_return retval = new CalculatorParser.call_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token EOL2=null;
        CalculatorParser.expression_return expression1 = null;


        Object EOL2_tree=null;

        try {
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:79:2: ( expression EOL )
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:79:4: expression EOL
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_expression_in_call353);
            expression1=expression();

            state._fsp--;

            adaptor.addChild(root_0, expression1.getTree());
            EOL2=(Token)match(input,EOL,FOLLOW_EOL_in_call355); 
            EOL2_tree = (Object)adaptor.create(EOL2);
            adaptor.addChild(root_0, EOL2_tree);


            		retval.type = (expression1!=null?expression1.type:null);
            		retval.value = (expression1!=null?expression1.value:null);
            	

            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "call"

    public static class expression_return extends ParserRuleReturnScope {
        public Number value;
        public Type type;
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "expression"
    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:86:1: expression returns [Number value, Type type] : t= term ( PLUS t= term | MINUS t= term )* ;
    public final CalculatorParser.expression_return expression() throws RecognitionException {
        CalculatorParser.expression_return retval = new CalculatorParser.expression_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token PLUS3=null;
        Token MINUS4=null;
        CalculatorParser.term_return t = null;


        Object PLUS3_tree=null;
        Object MINUS4_tree=null;

        try {
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:87:2: (t= term ( PLUS t= term | MINUS t= term )* )
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:87:4: t= term ( PLUS t= term | MINUS t= term )*
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_term_in_expression375);
            t=term();

            state._fsp--;

            adaptor.addChild(root_0, t.getTree());

            		retval.type = (t!=null?t.type:null);
            		retval.value = (t!=null?t.value:null);
            	
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:90:4: ( PLUS t= term | MINUS t= term )*
            loop1:
            do {
                int alt1=3;
                int LA1_0 = input.LA(1);

                if ( (LA1_0==PLUS) ) {
                    alt1=1;
                }
                else if ( (LA1_0==MINUS) ) {
                    alt1=2;
                }


                switch (alt1) {
            	case 1 :
            	    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:91:3: PLUS t= term
            	    {
            	    PLUS3=(Token)match(input,PLUS,FOLLOW_PLUS_in_expression383); 
            	    PLUS3_tree = (Object)adaptor.create(PLUS3);
            	    adaptor.addChild(root_0, PLUS3_tree);

            	    pushFollow(FOLLOW_term_in_expression387);
            	    t=term();

            	    state._fsp--;

            	    adaptor.addChild(root_0, t.getTree());

            	    			if (retval.type == Type.INTEGER && (t!=null?t.type:null) == Type.INTEGER) {
            	    				retval.type = Type.INTEGER;
            	    				retval.value = retval.value.intValue() + (t!=null?t.value:null).intValue();
            	    			} else {
            	    				retval.type = Type.FLOAT;
            	    				retval.value = retval.value.doubleValue() + (t!=null?t.value:null).doubleValue();
            	    			}
            	    		 

            	    }
            	    break;
            	case 2 :
            	    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:99:8: MINUS t= term
            	    {
            	    MINUS4=(Token)match(input,MINUS,FOLLOW_MINUS_in_expression393); 
            	    MINUS4_tree = (Object)adaptor.create(MINUS4);
            	    adaptor.addChild(root_0, MINUS4_tree);

            	    pushFollow(FOLLOW_term_in_expression397);
            	    t=term();

            	    state._fsp--;

            	    adaptor.addChild(root_0, t.getTree());

            	    			if (retval.type == Type.INTEGER && (t!=null?t.type:null) == Type.INTEGER) {
            	    				retval.type = Type.INTEGER;
            	    				retval.value = retval.value.intValue() - (t!=null?t.value:null).intValue();
            	    			} else {
            	    				retval.type = Type.FLOAT;
            	    				retval.value = retval.value.doubleValue() - (t!=null?t.value:null).doubleValue();
            	    			}
            	    		 

            	    }
            	    break;

            	default :
            	    break loop1;
                }
            } while (true);


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "expression"

    public static class term_return extends ParserRuleReturnScope {
        public Number value;
        public Type type;
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "term"
    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:112:1: term returns [Number value, Type type] : f= factor ( MULT f= factor | DIV f= factor | MOD f= factor )* ;
    public final CalculatorParser.term_return term() throws RecognitionException {
        CalculatorParser.term_return retval = new CalculatorParser.term_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token MULT5=null;
        Token DIV6=null;
        Token MOD7=null;
        CalculatorParser.factor_return f = null;


        Object MULT5_tree=null;
        Object DIV6_tree=null;
        Object MOD7_tree=null;

        try {
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:113:2: (f= factor ( MULT f= factor | DIV f= factor | MOD f= factor )* )
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:113:4: f= factor ( MULT f= factor | DIV f= factor | MOD f= factor )*
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_factor_in_term422);
            f=factor();

            state._fsp--;

            adaptor.addChild(root_0, f.getTree());

            		retval.type = (f!=null?f.type:null);
            		retval.value = (f!=null?f.value:null);
            	
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:116:4: ( MULT f= factor | DIV f= factor | MOD f= factor )*
            loop2:
            do {
                int alt2=4;
                switch ( input.LA(1) ) {
                case MULT:
                    {
                    alt2=1;
                    }
                    break;
                case DIV:
                    {
                    alt2=2;
                    }
                    break;
                case MOD:
                    {
                    alt2=3;
                    }
                    break;

                }

                switch (alt2) {
            	case 1 :
            	    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:117:3: MULT f= factor
            	    {
            	    MULT5=(Token)match(input,MULT,FOLLOW_MULT_in_term430); 
            	    MULT5_tree = (Object)adaptor.create(MULT5);
            	    adaptor.addChild(root_0, MULT5_tree);

            	    pushFollow(FOLLOW_factor_in_term434);
            	    f=factor();

            	    state._fsp--;

            	    adaptor.addChild(root_0, f.getTree());

            	    			if (retval.type == Type.INTEGER && (f!=null?f.type:null) == Type.INTEGER) {
            	    				retval.type = Type.INTEGER;
            	    				retval.value = retval.value.intValue() * (f!=null?f.value:null).intValue();
            	    			} else {
            	    				retval.type = Type.FLOAT;
            	    				retval.value = retval.value.doubleValue() * (f!=null?f.value:null).doubleValue();
            	    			}
            	    		

            	    }
            	    break;
            	case 2 :
            	    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:125:7: DIV f= factor
            	    {
            	    DIV6=(Token)match(input,DIV,FOLLOW_DIV_in_term440); 
            	    DIV6_tree = (Object)adaptor.create(DIV6);
            	    adaptor.addChild(root_0, DIV6_tree);

            	    pushFollow(FOLLOW_factor_in_term444);
            	    f=factor();

            	    state._fsp--;

            	    adaptor.addChild(root_0, f.getTree());

            	    			if (retval.type == Type.INTEGER && (f!=null?f.type:null) == Type.INTEGER) {
            	    				if ((f!=null?f.value:null).intValue() == 0) {
            	    					throw new ArithmeticException("line " + (DIV6!=null?DIV6.getLine():0) + ":" + (DIV6!=null?DIV6.getCharPositionInLine():0) + " Divide by Zero!");
            	    				} else {
            	    					retval.type = Type.INTEGER;
            	    					retval.value = retval.value.intValue() / (f!=null?f.value:null).intValue();
            	    				}
            	    			} else {
            	    				if ((f!=null?f.value:null).doubleValue() == 0.0f) {
            	    					throw new ArithmeticException("line " + (DIV6!=null?DIV6.getLine():0) + ":" + (DIV6!=null?DIV6.getCharPositionInLine():0) + " Divide by Zero!");
            	    				} else {
            	    					retval.type = Type.FLOAT;
            	    					retval.value = retval.value.doubleValue() / (f!=null?f.value:null).doubleValue();
            	    				}
            	    			}
            	    		

            	    }
            	    break;
            	case 3 :
            	    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:141:7: MOD f= factor
            	    {
            	    MOD7=(Token)match(input,MOD,FOLLOW_MOD_in_term450); 
            	    MOD7_tree = (Object)adaptor.create(MOD7);
            	    adaptor.addChild(root_0, MOD7_tree);

            	    pushFollow(FOLLOW_factor_in_term454);
            	    f=factor();

            	    state._fsp--;

            	    adaptor.addChild(root_0, f.getTree());

            	    			if (retval.type == Type.INTEGER && (f!=null?f.type:null) == Type.INTEGER) {
            	    				retval.type = Type.INTEGER;
            	    				int a = retval.value.intValue();
            	    				int b = (f!=null?f.value:null).intValue();
            	    				retval.value = a-a/b*b ;
            	    			} else {
            	    				throw new ArithmeticException("line " + (MOD7!=null?MOD7.getLine():0) + ":" + (MOD7!=null?MOD7.getCharPositionInLine():0) + " MOD operation is valid for Integers only!");
            	    			}
            	    		

            	    }
            	    break;

            	default :
            	    break loop2;
                }
            } while (true);


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "term"

    public static class atom_return extends ParserRuleReturnScope {
        public Number value;
        public Type type;
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "atom"
    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:154:1: atom returns [Number value, Type type] : ( NUMBER | LPAREN expression RPAREN | function );
    public final CalculatorParser.atom_return atom() throws RecognitionException {
        CalculatorParser.atom_return retval = new CalculatorParser.atom_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token NUMBER8=null;
        Token LPAREN9=null;
        Token RPAREN11=null;
        CalculatorParser.expression_return expression10 = null;

        CalculatorParser.function_return function12 = null;


        Object NUMBER8_tree=null;
        Object LPAREN9_tree=null;
        Object RPAREN11_tree=null;

        try {
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:155:2: ( NUMBER | LPAREN expression RPAREN | function )
            int alt3=3;
            switch ( input.LA(1) ) {
            case NUMBER:
                {
                alt3=1;
                }
                break;
            case LPAREN:
                {
                alt3=2;
                }
                break;
            case ABS:
            case SIN:
            case COS:
            case SQRT:
            case POW:
            case LN:
            case LOG:
                {
                alt3=3;
                }
                break;
            default:
                NoViableAltException nvae =
                    new NoViableAltException("", 3, 0, input);

                throw nvae;
            }

            switch (alt3) {
                case 1 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:155:4: NUMBER
                    {
                    root_0 = (Object)adaptor.nil();

                    NUMBER8=(Token)match(input,NUMBER,FOLLOW_NUMBER_in_atom476); 
                    NUMBER8_tree = (Object)adaptor.create(NUMBER8);
                    adaptor.addChild(root_0, NUMBER8_tree);


                    		String str = (NUMBER8!=null?NUMBER8.getText():null).trim();
                    		int index = (NUMBER8!=null?NUMBER8.getText():null).indexOf(".");
                    		if (index == str.length()-1) {
                    			str = str.substring(0, index);
                    		}
                    		if (str.indexOf(".") > -1) {
                    			retval.type = Type.FLOAT;
                    			retval.value = Double.valueOf(str);
                    		} else {
                    			retval.type = Type.INTEGER;
                    			retval.value = Integer.valueOf(str);
                    		}
                    	

                    }
                    break;
                case 2 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:168:6: LPAREN expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    LPAREN9=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_atom482); 
                    LPAREN9_tree = (Object)adaptor.create(LPAREN9);
                    adaptor.addChild(root_0, LPAREN9_tree);

                    pushFollow(FOLLOW_expression_in_atom484);
                    expression10=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, expression10.getTree());
                    RPAREN11=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_atom486); 
                    RPAREN11_tree = (Object)adaptor.create(RPAREN11);
                    adaptor.addChild(root_0, RPAREN11_tree);


                    		retval.type = (expression10!=null?expression10.type:null);
                    		retval.value = (expression10!=null?expression10.value:null);
                    	

                    }
                    break;
                case 3 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:171:6: function
                    {
                    root_0 = (Object)adaptor.nil();

                    pushFollow(FOLLOW_function_in_atom492);
                    function12=function();

                    state._fsp--;

                    adaptor.addChild(root_0, function12.getTree());

                    		retval.type = (function12!=null?function12.type:null);
                    		retval.value = (function12!=null?function12.value:null);
                    	

                    }
                    break;

            }
            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "atom"

    public static class factor_return extends ParserRuleReturnScope {
        public Number value;
        public Type type;
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "factor"
    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:178:1: factor returns [Number value, Type type] : ( ( PLUS )? atom | MINUS atom );
    public final CalculatorParser.factor_return factor() throws RecognitionException {
        CalculatorParser.factor_return retval = new CalculatorParser.factor_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token PLUS13=null;
        Token MINUS15=null;
        CalculatorParser.atom_return atom14 = null;

        CalculatorParser.atom_return atom16 = null;


        Object PLUS13_tree=null;
        Object MINUS15_tree=null;

        try {
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:179:2: ( ( PLUS )? atom | MINUS atom )
            int alt5=2;
            int LA5_0 = input.LA(1);

            if ( (LA5_0==PLUS||LA5_0==LPAREN||LA5_0==NUMBER||(LA5_0>=ABS && LA5_0<=LOG)) ) {
                alt5=1;
            }
            else if ( (LA5_0==MINUS) ) {
                alt5=2;
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 5, 0, input);

                throw nvae;
            }
            switch (alt5) {
                case 1 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:179:4: ( PLUS )? atom
                    {
                    root_0 = (Object)adaptor.nil();

                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:179:4: ( PLUS )?
                    int alt4=2;
                    int LA4_0 = input.LA(1);

                    if ( (LA4_0==PLUS) ) {
                        alt4=1;
                    }
                    switch (alt4) {
                        case 1 :
                            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:179:4: PLUS
                            {
                            PLUS13=(Token)match(input,PLUS,FOLLOW_PLUS_in_factor510); 
                            PLUS13_tree = (Object)adaptor.create(PLUS13);
                            adaptor.addChild(root_0, PLUS13_tree);


                            }
                            break;

                    }

                    pushFollow(FOLLOW_atom_in_factor513);
                    atom14=atom();

                    state._fsp--;

                    adaptor.addChild(root_0, atom14.getTree());

                    		retval.type = (atom14!=null?atom14.type:null);
                    		retval.value = (atom14!=null?atom14.value:null);
                    	

                    }
                    break;
                case 2 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:182:6: MINUS atom
                    {
                    root_0 = (Object)adaptor.nil();

                    MINUS15=(Token)match(input,MINUS,FOLLOW_MINUS_in_factor519); 
                    MINUS15_tree = (Object)adaptor.create(MINUS15);
                    adaptor.addChild(root_0, MINUS15_tree);

                    pushFollow(FOLLOW_atom_in_factor521);
                    atom16=atom();

                    state._fsp--;

                    adaptor.addChild(root_0, atom16.getTree());

                    		retval.type = (atom16!=null?atom16.type:null);
                    		if (retval.type  == Type.FLOAT) {
                    			retval.value = -(atom16!=null?atom16.value:null).doubleValue();
                    		} else {	//integer
                    			retval.value = -(atom16!=null?atom16.value:null).intValue();
                    		}
                    	

                    }
                    break;

            }
            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "factor"

    public static class function_return extends ParserRuleReturnScope {
        public Number value;
        public Type type;
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "function"
    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:192:1: function returns [Number value, Type type] : ( ABS LPAREN expression RPAREN | SIN LPAREN expression RPAREN | COS LPAREN expression RPAREN | SQRT LPAREN expression RPAREN | LN LPAREN expression RPAREN | LOG LPAREN expression RPAREN | POW LPAREN a= expression COMMA b= expression RPAREN );
    public final CalculatorParser.function_return function() throws RecognitionException {
        CalculatorParser.function_return retval = new CalculatorParser.function_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token ABS17=null;
        Token LPAREN18=null;
        Token RPAREN20=null;
        Token SIN21=null;
        Token LPAREN22=null;
        Token RPAREN24=null;
        Token COS25=null;
        Token LPAREN26=null;
        Token RPAREN28=null;
        Token SQRT29=null;
        Token LPAREN30=null;
        Token RPAREN32=null;
        Token LN33=null;
        Token LPAREN34=null;
        Token RPAREN36=null;
        Token LOG37=null;
        Token LPAREN38=null;
        Token RPAREN40=null;
        Token POW41=null;
        Token LPAREN42=null;
        Token COMMA43=null;
        Token RPAREN44=null;
        CalculatorParser.expression_return a = null;

        CalculatorParser.expression_return b = null;

        CalculatorParser.expression_return expression19 = null;

        CalculatorParser.expression_return expression23 = null;

        CalculatorParser.expression_return expression27 = null;

        CalculatorParser.expression_return expression31 = null;

        CalculatorParser.expression_return expression35 = null;

        CalculatorParser.expression_return expression39 = null;


        Object ABS17_tree=null;
        Object LPAREN18_tree=null;
        Object RPAREN20_tree=null;
        Object SIN21_tree=null;
        Object LPAREN22_tree=null;
        Object RPAREN24_tree=null;
        Object COS25_tree=null;
        Object LPAREN26_tree=null;
        Object RPAREN28_tree=null;
        Object SQRT29_tree=null;
        Object LPAREN30_tree=null;
        Object RPAREN32_tree=null;
        Object LN33_tree=null;
        Object LPAREN34_tree=null;
        Object RPAREN36_tree=null;
        Object LOG37_tree=null;
        Object LPAREN38_tree=null;
        Object RPAREN40_tree=null;
        Object POW41_tree=null;
        Object LPAREN42_tree=null;
        Object COMMA43_tree=null;
        Object RPAREN44_tree=null;

        try {
            // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:193:2: ( ABS LPAREN expression RPAREN | SIN LPAREN expression RPAREN | COS LPAREN expression RPAREN | SQRT LPAREN expression RPAREN | LN LPAREN expression RPAREN | LOG LPAREN expression RPAREN | POW LPAREN a= expression COMMA b= expression RPAREN )
            int alt6=7;
            switch ( input.LA(1) ) {
            case ABS:
                {
                alt6=1;
                }
                break;
            case SIN:
                {
                alt6=2;
                }
                break;
            case COS:
                {
                alt6=3;
                }
                break;
            case SQRT:
                {
                alt6=4;
                }
                break;
            case LN:
                {
                alt6=5;
                }
                break;
            case LOG:
                {
                alt6=6;
                }
                break;
            case POW:
                {
                alt6=7;
                }
                break;
            default:
                NoViableAltException nvae =
                    new NoViableAltException("", 6, 0, input);

                throw nvae;
            }

            switch (alt6) {
                case 1 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:194:2: ABS LPAREN expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    ABS17=(Token)match(input,ABS,FOLLOW_ABS_in_function541); 
                    ABS17_tree = (Object)adaptor.create(ABS17);
                    adaptor.addChild(root_0, ABS17_tree);

                    LPAREN18=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_function543); 
                    LPAREN18_tree = (Object)adaptor.create(LPAREN18);
                    adaptor.addChild(root_0, LPAREN18_tree);

                    pushFollow(FOLLOW_expression_in_function545);
                    expression19=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, expression19.getTree());
                    RPAREN20=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_function547); 
                    RPAREN20_tree = (Object)adaptor.create(RPAREN20);
                    adaptor.addChild(root_0, RPAREN20_tree);


                    		retval.type = (expression19!=null?expression19.type:null);
                    		if ((expression19!=null?expression19.type:null) == Type.INTEGER) {
                    			retval.value = Math.abs((expression19!=null?expression19.value:null).intValue());
                    		} else {
                    			retval.value = Math.abs((expression19!=null?expression19.value:null).doubleValue());
                    		}
                    	

                    }
                    break;
                case 2 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:201:6: SIN LPAREN expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    SIN21=(Token)match(input,SIN,FOLLOW_SIN_in_function553); 
                    SIN21_tree = (Object)adaptor.create(SIN21);
                    adaptor.addChild(root_0, SIN21_tree);

                    LPAREN22=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_function555); 
                    LPAREN22_tree = (Object)adaptor.create(LPAREN22);
                    adaptor.addChild(root_0, LPAREN22_tree);

                    pushFollow(FOLLOW_expression_in_function557);
                    expression23=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, expression23.getTree());
                    RPAREN24=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_function559); 
                    RPAREN24_tree = (Object)adaptor.create(RPAREN24);
                    adaptor.addChild(root_0, RPAREN24_tree);


                    		retval.type = Type.FLOAT;
                    		retval.value = Math.sin((expression23!=null?expression23.value:null).doubleValue());
                    	

                    }
                    break;
                case 3 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:204:6: COS LPAREN expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    COS25=(Token)match(input,COS,FOLLOW_COS_in_function565); 
                    COS25_tree = (Object)adaptor.create(COS25);
                    adaptor.addChild(root_0, COS25_tree);

                    LPAREN26=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_function567); 
                    LPAREN26_tree = (Object)adaptor.create(LPAREN26);
                    adaptor.addChild(root_0, LPAREN26_tree);

                    pushFollow(FOLLOW_expression_in_function569);
                    expression27=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, expression27.getTree());
                    RPAREN28=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_function571); 
                    RPAREN28_tree = (Object)adaptor.create(RPAREN28);
                    adaptor.addChild(root_0, RPAREN28_tree);


                    		retval.type = Type.FLOAT;
                    		retval.value = Math.cos((expression27!=null?expression27.value:null).doubleValue());
                    	

                    }
                    break;
                case 4 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:207:6: SQRT LPAREN expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    SQRT29=(Token)match(input,SQRT,FOLLOW_SQRT_in_function577); 
                    SQRT29_tree = (Object)adaptor.create(SQRT29);
                    adaptor.addChild(root_0, SQRT29_tree);

                    LPAREN30=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_function579); 
                    LPAREN30_tree = (Object)adaptor.create(LPAREN30);
                    adaptor.addChild(root_0, LPAREN30_tree);

                    pushFollow(FOLLOW_expression_in_function581);
                    expression31=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, expression31.getTree());
                    RPAREN32=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_function583); 
                    RPAREN32_tree = (Object)adaptor.create(RPAREN32);
                    adaptor.addChild(root_0, RPAREN32_tree);


                    		double v = (expression31!=null?expression31.value:null).doubleValue();
                    		if (v < 0.0f) {
                    			throw new ArithmeticException("line " + (SQRT29!=null?SQRT29.getLine():0) + ":" + (SQRT29!=null?SQRT29.getCharPositionInLine():0) + " Square Root of negative number [" + v + "]!");
                    		} else {
                    			retval.type = Type.FLOAT;
                    			retval.value = Math.sqrt(v);
                    		}
                    	

                    }
                    break;
                case 5 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:215:6: LN LPAREN expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    LN33=(Token)match(input,LN,FOLLOW_LN_in_function589); 
                    LN33_tree = (Object)adaptor.create(LN33);
                    adaptor.addChild(root_0, LN33_tree);

                    LPAREN34=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_function591); 
                    LPAREN34_tree = (Object)adaptor.create(LPAREN34);
                    adaptor.addChild(root_0, LPAREN34_tree);

                    pushFollow(FOLLOW_expression_in_function593);
                    expression35=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, expression35.getTree());
                    RPAREN36=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_function595); 
                    RPAREN36_tree = (Object)adaptor.create(RPAREN36);
                    adaptor.addChild(root_0, RPAREN36_tree);


                    		double v = (expression35!=null?expression35.value:null).doubleValue();
                    		if (v <= 0.0f) {
                    			throw new ArithmeticException("line " + (LN33!=null?LN33.getLine():0) + ":" + (LN33!=null?LN33.getCharPositionInLine():0) + " Ln of negative number or Zero [" + v + "]!");
                    		} else {
                    			retval.type = Type.FLOAT;
                    			retval.value = Math.log(v);
                    		}
                    	

                    }
                    break;
                case 6 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:223:6: LOG LPAREN expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    LOG37=(Token)match(input,LOG,FOLLOW_LOG_in_function601); 
                    LOG37_tree = (Object)adaptor.create(LOG37);
                    adaptor.addChild(root_0, LOG37_tree);

                    LPAREN38=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_function603); 
                    LPAREN38_tree = (Object)adaptor.create(LPAREN38);
                    adaptor.addChild(root_0, LPAREN38_tree);

                    pushFollow(FOLLOW_expression_in_function605);
                    expression39=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, expression39.getTree());
                    RPAREN40=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_function607); 
                    RPAREN40_tree = (Object)adaptor.create(RPAREN40);
                    adaptor.addChild(root_0, RPAREN40_tree);


                    		double v = (expression39!=null?expression39.value:null).doubleValue();
                    		if (v <= 0.0f) {
                    			throw new ArithmeticException("line " + (LOG37!=null?LOG37.getLine():0) + ":" + (LOG37!=null?LOG37.getCharPositionInLine():0) + " Log of negative number or Zero [" + v + "]!");
                    		} else {
                    			retval.type = Type.FLOAT;
                    			retval.value = Math.log10(v);
                    		}
                    	

                    }
                    break;
                case 7 :
                    // D:\\develop\\experiments\\astudy\\base\\astudy\\parser\\calc\\Calculator.g:231:6: POW LPAREN a= expression COMMA b= expression RPAREN
                    {
                    root_0 = (Object)adaptor.nil();

                    POW41=(Token)match(input,POW,FOLLOW_POW_in_function613); 
                    POW41_tree = (Object)adaptor.create(POW41);
                    adaptor.addChild(root_0, POW41_tree);

                    LPAREN42=(Token)match(input,LPAREN,FOLLOW_LPAREN_in_function616); 
                    LPAREN42_tree = (Object)adaptor.create(LPAREN42);
                    adaptor.addChild(root_0, LPAREN42_tree);

                    pushFollow(FOLLOW_expression_in_function620);
                    a=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, a.getTree());
                    COMMA43=(Token)match(input,COMMA,FOLLOW_COMMA_in_function622); 
                    COMMA43_tree = (Object)adaptor.create(COMMA43);
                    adaptor.addChild(root_0, COMMA43_tree);

                    pushFollow(FOLLOW_expression_in_function626);
                    b=expression();

                    state._fsp--;

                    adaptor.addChild(root_0, b.getTree());
                    RPAREN44=(Token)match(input,RPAREN,FOLLOW_RPAREN_in_function628); 
                    RPAREN44_tree = (Object)adaptor.create(RPAREN44);
                    adaptor.addChild(root_0, RPAREN44_tree);


                    		retval.type = Type.FLOAT;
                    		retval.value = Math.pow((a!=null?a.value:null).doubleValue(), (b!=null?b.value:null).doubleValue());
                    	

                    }
                    break;

            }
            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "function"

    // Delegated rules


 

    public static final BitSet FOLLOW_expression_in_call353 = new BitSet(new long[]{0x0000000000020000L});
    public static final BitSet FOLLOW_EOL_in_call355 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_term_in_expression375 = new BitSet(new long[]{0x0000000000000032L});
    public static final BitSet FOLLOW_PLUS_in_expression383 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_term_in_expression387 = new BitSet(new long[]{0x0000000000000032L});
    public static final BitSet FOLLOW_MINUS_in_expression393 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_term_in_expression397 = new BitSet(new long[]{0x0000000000000032L});
    public static final BitSet FOLLOW_factor_in_term422 = new BitSet(new long[]{0x00000000000001C2L});
    public static final BitSet FOLLOW_MULT_in_term430 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_factor_in_term434 = new BitSet(new long[]{0x00000000000001C2L});
    public static final BitSet FOLLOW_DIV_in_term440 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_factor_in_term444 = new BitSet(new long[]{0x00000000000001C2L});
    public static final BitSet FOLLOW_MOD_in_term450 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_factor_in_term454 = new BitSet(new long[]{0x00000000000001C2L});
    public static final BitSet FOLLOW_NUMBER_in_atom476 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_LPAREN_in_atom482 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_atom484 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_atom486 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_function_in_atom492 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_PLUS_in_factor510 = new BitSet(new long[]{0x0000000003F88410L});
    public static final BitSet FOLLOW_atom_in_factor513 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_MINUS_in_factor519 = new BitSet(new long[]{0x0000000003F88410L});
    public static final BitSet FOLLOW_atom_in_factor521 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ABS_in_function541 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_function543 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function545 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_function547 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_SIN_in_function553 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_function555 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function557 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_function559 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_COS_in_function565 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_function567 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function569 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_function571 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_SQRT_in_function577 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_function579 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function581 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_function583 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_LN_in_function589 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_function591 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function593 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_function595 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_LOG_in_function601 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_function603 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function605 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_function607 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_POW_in_function613 = new BitSet(new long[]{0x0000000000000400L});
    public static final BitSet FOLLOW_LPAREN_in_function616 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function620 = new BitSet(new long[]{0x0000000000000200L});
    public static final BitSet FOLLOW_COMMA_in_function622 = new BitSet(new long[]{0x0000000003F88430L});
    public static final BitSet FOLLOW_expression_in_function626 = new BitSet(new long[]{0x0000000000000800L});
    public static final BitSet FOLLOW_RPAREN_in_function628 = new BitSet(new long[]{0x0000000000000002L});

}